#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <unistd.h>
#include<QThread>


int play_flag = false;
int favorite_flag = false;
int menu_flag = false;
int circle_play = true;//false=随机播放,true=循环列表

int chosenid = 1;
int chnid_nums = 0;
QString chnid_list[10];
int angle = 0;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("音乐播放器");
    this->setFixedSize(800,500);




    timer_cd = new QTimer;
    // connect(timer_cd,&QTimer::timeout,this,&MainWindow::cd_timeout);

    timer_getPosTime = new QTimer;
    // connect(timer_getPosTime,&QTimer::timeout,this,&MainWindow::getPosTime_timeout);
    timer_getPosTime->start(900);


    /* udp套接字 */
    udpSocket = new QUdpSocket(this);

    /* 参数1是设置IP_MULTICAST_TTL套接字选项允许应用程序主要限制数据包在Internet中的生存时间，
     * 并防止其无限期地循环，数据报跨一个路由会减一，默认值为1，表示多播仅适用于本地子网。*/
    udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1);


    parts_init();
    QSlider_init();
    QListWidget_init();

    connect(pause_button,&QPushButton::clicked,this,&MainWindow::pause_clicked);
    connect(prev_button,&QPushButton::clicked,this,&MainWindow::prev_clicked);
    connect(next_button,&QPushButton::clicked,this,&MainWindow::next_clicked);
    //connect(exit_button,&QPushButton::clicked,this,&MainWindow::exit_clicked);
     connect(favorite_button,&QPushButton::clicked,this,&MainWindow::favorite_clicked);
    // connect(listcircle_button,&QPushButton::clicked,this,&MainWindow::listcircle_clicked);
    connect(menu_button,&QPushButton::clicked,this,&MainWindow::menu_clicked);




    connect(udpSocket, SIGNAL(readyRead()),
            this, SLOT(receiveMessages()));
    connect(udpSocket,
            SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,
            SLOT(socketStateChange(QAbstractSocket::SocketState)));

    int ret = pipe(fd);
    if(ret == 0)
    {
        printf("fd[0]===%d, fd[1] === %d\n", fd[0], fd[1]);
    }
    pid_t pid = fork();
    //this->pid = pid;
    if(pid < 0)
    {
        perror("error pid");
    }
    else if(pid == 0)
    {


        ::close(fd[1]);   // 0:read, 1:write
        dup2(fd[0], 0); // set pd[0] as stdin
        if (fd[0] > 0)  // close pd[0]
            ::close(fd[0]);
        execl("/bin/sh", "sh", "-c", "/usr/bin/mpg123  -   > /dev/null", NULL);
    }

    joinGroup();
}

MainWindow::~MainWindow()
{

    delete ui;
}

void MainWindow::parts_init()
{
    QFont font;

    label_cd = new QLabel(this);
    label_cd->setGeometry(390,30,300,300);
    label_cd->setStyleSheet("border-image: url(:/images/cd.png);");

    lable_SongTitle = new QLabel(this);
    lable_SongTitle->setGeometry(310,360,350,25);
    font.setPointSize(14);
    lable_SongTitle->setFont(font);
    lable_SongTitle->setStyleSheet("QLabel{color:white;}QLabel{background:transparent}");
    lable_SongTitle->setText("音乐PLAY");
    lable_SongTitle->setAlignment(Qt::AlignVCenter|Qt::AlignLeft);

    lable_Songcurrent_time = new QLabel(this);;
    lable_Songcurrent_time->setGeometry(650,365,60,20);
    font.setPointSize(10);
    lable_Songcurrent_time->setFont(font);
    lable_Songcurrent_time->setStyleSheet("QLabel{color:white;}QLabel{background:transparent}");
    lable_Songcurrent_time->setText("00:00 / ");
    lable_Songcurrent_time->setAlignment(Qt::AlignVCenter|Qt::AlignLeft);

    lable_SongTotal_time = new QLabel(this);
    lable_SongTotal_time->setGeometry(700,365,60,20);
    font.setPointSize(10);
    lable_SongTotal_time->setFont(font);
    lable_SongTotal_time->setStyleSheet("QLabel{color:white;}QLabel{background:transparent}");
    lable_SongTotal_time->setText("00:00");
    lable_SongTotal_time->setAlignment(Qt::AlignVCenter|Qt::AlignLeft);

    prev_button = new QPushButton;
    prev_button->setFixedSize(75,75);//防止它变大或者变小
    prev_button->setStyleSheet("border-image: url(:/images/btn_previous1.png);");
    prev_button->setIconSize(QSize(75,75));//设置图标大小
    prev_button->setFlat(true);
    prev_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    prev_button->setParent(this);//按钮一定要设置父窗口，不然显示不出
    prev_button->move(20,400);

    pause_button = new QPushButton;
    pause_button->setFixedSize(75,75);//防止它变大或者变小
    //pause_button->setIcon(QIcon(":/images/btn_play.png"));//这种点击效果不好看
    pause_button->setStyleSheet("border-image: url(:/images/btn_play1.png);");
    pause_button->setIconSize(QSize(75,75));//设置图标大小
    pause_button->setFlat(true);
    pause_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    pause_button->setParent(this);
    pause_button->move(100,400);


    next_button = new QPushButton;
    next_button->setFixedSize(75,75);//防止它变大或者变小
    next_button->setStyleSheet("border-image: url(:/images/btn_next1.png);");
    next_button->setIconSize(QSize(75,75));//设置图标大小
    next_button->setFlat(true);
    next_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    next_button->setParent(this);
    next_button->move(180,400);

    /*
    exit_button = new QPushButton;
    exit_button->setFixedSize(75,75);//防止它变大或者变小
    exit_button->setIcon(QIcon(":/images/btn_exit.png"));
    exit_button->setIconSize(QSize(75,75));//设置图标大小
    exit_button->setFlat(true);
    exit_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    exit_button->setParent(this);
    exit_button->move(760,450);
    */
    addfile_button = new QPushButton;
    addfile_button->setFixedSize(43,43);//防止它变大或者变小
    addfile_button->setStyleSheet("border-image: url(:/images/openfile.png);");
    addfile_button->setIconSize(QSize(43,43));//设置图标大小
    addfile_button->setFlat(true);
    addfile_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    addfile_button->setParent(this);
    addfile_button->move(200,0);
    addfile_button->setVisible(false);

    favorite_button = new QPushButton;
    favorite_button->setFixedSize(25,25);//防止它变大或者变小
    favorite_button->setIcon(QIcon(":/images/btn_favorite_no.png"));
    favorite_button->setIconSize(QSize(25,25));//设置图标大小
    favorite_button->setFlat(true);
    favorite_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    favorite_button->setParent(this);
    favorite_button->move(310,430);

    listcircle_button = new QPushButton;
    listcircle_button->setFixedSize(25,25);//防止它变大或者变小
    listcircle_button->setIcon(QIcon(":/images/btn_listcircle.png"));
    listcircle_button->setIconSize(QSize(25,25));//设置图标大小
    listcircle_button->setFlat(true);
    listcircle_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    listcircle_button->setParent(this);
    listcircle_button->move(388,430);

    menu_button = new QPushButton;
    menu_button->setFixedSize(25,25);//防止它变大或者变小
    menu_button->setIcon(QIcon(":/images/btn_menu1.png"));
    menu_button->setIconSize(QSize(25,25));//设置图标大小
    menu_button->setFlat(true);
    menu_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    menu_button->setParent(this);
    menu_button->move(700,430);

    timer_vol = new QTimer(this);//音量显示定时器
    volume_button = new QPushButton;
    volume_button->setFixedSize(25,25);//防止它变大或者变小
    volume_button->setIcon(QIcon(":/images/btn_volume.png"));
    volume_button->setIconSize(QSize(25,25));//设置图标大小
    volume_button->setFlat(true);
    volume_button->setFocusPolicy(Qt::NoFocus);//去除虚线边框
    volume_button->setParent(this);
    volume_button->move(544,430);


    songList = new QListWidget(this);
    songList->clear();                                                  //清空列表
    songList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);       //关闭水平滚动条
    songList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);     //关闭垂直滚动条
    songList->setFrameShape(QFrame::NoFrame);                      //去除边框
    songList->setGeometry(0,35,230,370);//设置歌曲列表位置与大小
    songList->setVisible(false);

}


void MainWindow::joinGroup()
{
    /* 获取端口 */
    quint16 port = DEFAULT_PORT;
    /* 获取组播地址 */
    QHostAddress groupAddr = QHostAddress(MUL_CASTADDR);

    /* 绑定端口需要在socket的状态为UnconnectedState */
    if (udpSocket->state() != QAbstractSocket::UnconnectedState)
        udpSocket->close();

    /* 加入组播前必须先绑定端口 */
    if (udpSocket->bind(QHostAddress::AnyIPv4,
                        port, QUdpSocket::ShareAddress)) {

        /* 加入组播组，返回结果给ok变量 */
        bool ok = udpSocket->joinMulticastGroup(groupAddr);
        printf("nulticast state %d", ok);

    }
}


/* 客户端接收消息 */
void MainWindow::receiveMessages()
{
    /* 局部变量，用于获取发送者的IP和端口 */
    QHostAddress peerAddr;
    quint16 peerPort;

    /* 如果有数据已经准备好 */
    while (udpSocket->hasPendingDatagrams()) {
        /* udpSocket发送的数据报是QByteArray类型的字节数组 */
        QByteArray datagram;

        /* 重新定义数组的大小 */
        datagram.resize(udpSocket->pendingDatagramSize());

        /* 读取数据，并获取发送方的IP地址和端口 */


        struct  msg_list_st *list = (struct  msg_list_st *)malloc(65536);


        qint64 data_len ;


        data_len =   udpSocket->readDatagram((char *)list,
                                             datagram.size(),
                                             &peerAddr,
                                             &peerPort);



        if (list->chnid == 0) {
            chnid_nums = 0;
            struct msg_listentry_st *pos;
            char str[1024];
            for (pos =  (msg_listentry_st *) ((char *)list +1); (char *)pos < ((char *)list + data_len); pos = (msg_listentry_st *)(((char *)pos) + (11)))
            {
                sprintf(str,"channel:%d#%s\n", pos->chnid, pos->desc);
                chnid_list[chnid_nums++] = str;

            }
            /*free list*/
            free(list);
        }




        if(angle++ ==360)
            angle = 0;



        struct msg_channel_st *msg_channel;
        msg_channel = (  struct msg_channel_st *)malloc(65535);
        if (msg_channel == NULL)
        {
            perror("malloc()");
            exit(1);
        }
        data_len =  udpSocket->readDatagram((char *)msg_channel,
                                            datagram.size(),
                                            &peerAddr,
                                            &peerPort);

        if(data_len < sizeof(msg_channel))
        {
            fprintf(stderr, "msg_channel too small\n");
            continue;
        }
        if(msg_channel->chinid == chosenid)
        {
            fprintf(stdout, "accepted msg : %d \n", msg_channel->chinid);
            char str[122880];
            memcpy( (void *)str,msg_channel->data,data_len-sizeof(chnid_t));
            if(play_flag == true)
            {
                QThread::msleep(1000);
                if (write(fd[1], str, data_len-sizeof(chnid_t)) < 0) {
                    perror("write");
                    exit(1);
                }






                QMatrix matrix;
                matrix.rotate(angle);

            //设定图片的大小；
                QImage Image = QImage(":/images/cd.png");
                QPixmap pixmap = QPixmap::fromImage(Image);
                QPixmap fixpixmap = pixmap.scaled(300,300,Qt::IgnoreAspectRatio
                                        ,Qt::SmoothTransformation);


                label_cd->setPixmap((fixpixmap)
                            .transformed(matrix,Qt::SmoothTransformation));
                label_cd->setAlignment(Qt::AlignCenter);

            }


        }
        free(msg_channel);


    }
}


/* socket状态改变 */
void MainWindow::socketStateChange(QAbstractSocket::SocketState state)
{
    switch (state) {
    case QAbstractSocket::UnconnectedState:
        qDebug()<<("scoket状态：UnconnectedState");
        break;
    case QAbstractSocket::ConnectedState:
        qDebug()<<("scoket状态：ConnectedState");
        break;
    case QAbstractSocket::ConnectingState:
        qDebug()<<("scoket状态：ConnectingState");
        break;
    case QAbstractSocket::HostLookupState:
        qDebug()<<("scoket状态：HostLookupState");
        break;
    case QAbstractSocket::ClosingState:
        qDebug()<<("scoket状态：ClosingState");
        break;
    case QAbstractSocket::ListeningState:
        qDebug()<<("scoket状态：ListeningState");
        break;
    case QAbstractSocket::BoundState:
        qDebug()<<("scoket状态：BoundState");
        break;
    default:
        break;
    }
}





void MainWindow::QSlider_init()
{
    //播放进度滑块
    music_Slider = new QSlider(Qt::Horizontal, this);     //设置为水平滑动条
    music_Slider->setGeometry(310,385,450,40);            //设置位置和大小
    music_Slider->setRange(0,100);
    music_Slider->setValue(0);
    music_Slider->setTracking(false);                     //禁用追踪
    music_Slider->setStyleSheet(                          //设置滑块样式,如果写到qss样式文件里是不可以注释的
                                                          //滑条
                                                          "QSlider::groove:horizontal{"
                                                          " border: 1px solid #999999;"
                                                          " height: 5px; "

                                                          "position: absolute;"
                                                          "border-radius :3px;"
                                                          " background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);"
                                                          " margin: 1px 0;"
                                                          " left: 3px; right: 3px;"
                                                          "}"
                                                          //小滑块
                                                          "QSlider::handle:horizontal {"
                                                          " background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f);"
                                                          "border: 1px solid #5c5c5c;"
                                                          "width: 12px;"
                                                          " height: 12px; "
                                                          "margin: -2px -1; "
                                                          "  border-radius: 4px;"
                                                          "}"
                                                          //滑块滑过改变样式
                                                          " QSlider::add-page:horizontal {"
                                                          "border-radius :2px;"
                                                          " margin: 1px 1;"
                                                          "background: white;"
                                                          "}"

                                                          "QSlider::sub-page:horizontal {"
                                                          "border-radius :2px;"
                                                          " margin: 1px 1;"
                                                          "  background-color:#86dfc6;"
                                                          "}"
                                                          );



}





void MainWindow::pause_clicked()
{

    if(play_flag == true){
        timer_cd->stop();
        pause_button->setIcon(QIcon(":/images/btn_play1.png"));
        play_flag = false;
    }
    else if(play_flag == false){
        timer_cd->start();
        pause_button->setIcon(QIcon(":/images/btn_pause1.png"));
        play_flag = true;
    }
    char str[10];
    sprintf(str, "频道:%d \n",chosenid);
    lable_SongTitle->setText(str);

}

void MainWindow::prev_clicked()
{


    play_flag = true;
    pause_button->setIcon(QIcon(":/images/btn_pause2.png"));
    chosenid--;
    if(chosenid < 1)
    {
        chosenid = 1;
    }
    char str[10];
    sprintf(str, "频道:%d \n",chosenid);
    lable_SongTitle->setText(str);

}

void MainWindow::next_clicked()
{
    /*timer_getPosTime->stop();
    timer_getPosTime->start(900);
    music_Slider->setValue(0);*/

    play_flag = true;
    pause_button->setIcon(QIcon(":/images/btn_pause1.png"));
    chosenid++;
    if(chosenid > chnid_nums)
    {
        chosenid = chnid_nums;
    }
    char str[10];
    sprintf(str, "频道:%d \n",chosenid);
    lable_SongTitle->setText(str);


}



void MainWindow::QListWidget_init()
{

    scanSong();

    QListWidgetItem *item ;
    for (int i = 0; i < chnid_nums; ++i) {
        //songList->addItem(QFileInfo(List[i]).fileName());//将(歌曲)List用addItem函数加入到songList里
        songList->addItem(chnid_list[i]);
       //qDebug() << chnid_list[i] <<endl;
       // item->setText("123");

        item = songList->item(i);
        item->setSizeHint(QSize(40,40));
        item->setForeground(Qt::green);
        item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    }

}


void MainWindow::scanSong()
{
    QDir dir("/home/jemee/C_project/QT/40_qlistview/myMusic");//指定需要扫描歌曲目录的路径
    if (dir.exists()) {
        QStringList filter;
        filter << "*.mp3"
               << "*.wav";                                           // 包含所有.mp3 .wav后缀的文件
        songFilelist = dir.entryInfoList(filter, QDir::Files);      // 获得目录下的所有.mp3 .wav后缀的文件
    }
}



void MainWindow::favorite_clicked()
{
    if(favorite_flag == false){
       favorite_button->setIcon(QIcon(":/images/btn_favorite_yes.png"));
       favorite_flag = true;
    }else {
        favorite_button->setIcon(QIcon(":/images/btn_favorite_no.png"));
        favorite_flag = false;
    }

}



void MainWindow::menu_clicked()
{
    if(menu_flag == false){
        songList->setVisible(true);
        addfile_button->setVisible(true);
        menu_flag = true;
    }else {
        songList->setVisible(false);
        addfile_button->setVisible(false);
        menu_flag = false;
    }
    QListWidget_init();
}



